package com.nan.bytecode.asm;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_SUPER;
import static org.objectweb.asm.Opcodes.IADD;
import static org.objectweb.asm.Opcodes.ILOAD;
import static org.objectweb.asm.Opcodes.IRETURN;
import static org.objectweb.asm.Opcodes.RETURN;
import static org.objectweb.asm.Opcodes.V1_8;

public class ASMCalc {
    public static byte[] generate() {
        /* 如果生成的类要生成对象，必须添加 <init> 方法*/
        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);

        /*添加构造方法,默认会调用父类的无参构造方法*/
        {
            MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            // 局部变量0号槽为this，也就是将this变量入栈
            methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
            methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
            methodVisitor.visitInsn(RETURN);
        }
        /*创建Calc类，并添加add方法*/
        {
            classWriter.visit(V1_8, ACC_PUBLIC | ACC_SUPER, "com/nan/bytecode/asm/Calc", null, "java/lang/Object", null);
            MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "add", "(II)I", null, null);
            methodVisitor.visitVarInsn(ILOAD, 1);
            methodVisitor.visitVarInsn(ILOAD, 2);
            methodVisitor.visitInsn(IADD);
            methodVisitor.visitInsn(IRETURN);
            methodVisitor.visitEnd();
        }
        classWriter.visitEnd();
        return classWriter.toByteArray();
    }
}
